跳到主要内容

高基数问题 Cardinality

高基数是数据库避不开的一个话题,对于 Mysql 这种 DB 来讲,基数是指特定列或字段中包含的唯一值 的数量。基数越低,列中重复的元素越多。对于时序数据库而言,就是 tags、label 这种标签值的数量 多少。

比如 Prometheus 中如果有一个指标 http_request_count{method="get",path="/abc",originIP="1.1.1.1"} 表示访问量,method 表

示请求方法,originIP 是客户端 IP,method的枚举值是有限的,但 originIP 却是无限的,加上其他 label 的排列组合就无穷大了,也没有任何关联特征,因此这种高基数不适合作为 Metric 的 label,真要 的提取originIP,应该用日志的方式,而不是 Metric 监控

时序数据库会为这些 Label 建立索引,以提高查询性能,以便您可以快速找到与所有指定标签匹配的 值。如果值的数量过多,索引是没有意义的,尤其是做 P95 等计算的时候,要扫描大量 Series 数据

官方文档中对于Label 的建议

CAUTION: Remember that every unique combination of key-value label pairs
represents a new time series, which can dramatically increase the amount of data
stored. Do not use labels to store dimensions with high cardinality (many
different label values), such as user IDs, email addresses, or other unbounded
sets of values.

如何查看当前的Label 分布情况呢,可以使用 Prometheus提供的Tsdb工具。可以使用命令行查看,也 可以在 2.16 版本以上的 Prometheus Graph 查看

[work@xxx bin]$ ./tsdb analyze .. /data/prometheus/
Block ID: 01E41588AJNGM31SPGHYA3XSXG
Duration: 2homos
Series:955372
Label names:01
Postings (unique label pairs): 30757
Postings entries (total label pairs): 10842822